package top.tupobi.zing.mvp.presenter;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.EditText;

import androidx.appcompat.app.AlertDialog;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.SizeUtils;
import com.blankj.utilcode.util.StringUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.google.gson.Gson;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import top.tupobi.zing.InfoRecord;
import top.tupobi.zing.R;
import top.tupobi.zing.base.BasePresenter;
import top.tupobi.zing.custom_view.FriendApplyListPop;
import top.tupobi.zing.listener.OnCheckFriendApplyCallback;
import top.tupobi.zing.listener.OnFriendApplyResult;
import top.tupobi.zing.mvp.model.FriendApply;
import top.tupobi.zing.mvp.model.FriendModel;
import top.tupobi.zing.mvp.model.GetFriendListResponseModel;
import top.tupobi.zing.mvp.model.GetMessageResponseModel;
import top.tupobi.zing.mvp.model.HasNewFriendResponseModel;
import top.tupobi.zing.mvp.model.HttpResult;
import top.tupobi.zing.mvp.model.LoginResponseModel;
import top.tupobi.zing.mvp.model.NewFriendListResponseModel;
import top.tupobi.zing.mvp.model.TbMessage;
import top.tupobi.zing.mvp.model.UploadAvatarResponseModel;
import top.tupobi.zing.mvp.model.UploadNicknameResponseModel;
import top.tupobi.zing.mvp.view.IChatView;
import top.tupobi.zing.network.DefaultObserver;
import top.tupobi.zing.network.HttpConfig;
import top.tupobi.zing.network.beiyong.NetWorkBeiyong;
import top.tupobi.zing.network.beiyong.RxUtils;
import top.tupobi.zing.service.IMService;
import top.tupobi.zing.service.socket.listener.SocketResponseListener;
import top.tupobi.zing.service.socket.packet.DataType;
import top.tupobi.zing.service.socket.packet.SocketPacket;
import top.tupobi.zing.utils.NotificationUtils;

public class ChatPresenter extends BasePresenter<IChatView> implements SocketResponseListener {

    private IMServiceConnection mIMServiceConnection;
    private IMService.IMBinder mIMBinder;

    @Override
    public void onAddFriendResponse(String message) {
        mView.onAddFriendResponse(message);
    }

    @Override
    public void onNewFriendApply(String fromUsername) {
        // 在这里判断activity是否已经被销毁
        switch (mActivityStatus) {
            case BasePresenter.ACTIVITY_STATUS_DESTROYED:
                break;
            case BasePresenter.ACTIVITY_STATUS_FRONT:
            case BasePresenter.ACTIVITY_STATUS_HIDE:
                mView.onNewFriendApplyToastAndUpdateMenuUI(fromUsername);
                break;
        }
        InfoRecord.setHasNewFriend(true);
        NotificationUtils.startNotificationManager("新的消息", R.mipmap.icon_app, "收到一条好友申请");
    }

    @Override
    public void onSendMessageResult(String data) {
        TbMessage message = new Gson().fromJson(data, TbMessage.class);
        if (message.getMessageStatus() == DataType.MESSAGE_TYPE_STATUS_SEND_FAIL) {
            // 发送失败
            toast("发送消息失败");
        } else {
            // 消息发送成功
            // 插入本地数据库，通知menu是否更新，选中当前人不更新
            mView.messageSendSuccess(message);
        }
    }

    @Override
    public void onReceiveMessage(String data) {
        // 通知menu是否更新，选中当前人不更新，判断是否发送通知
        TbMessage message = new Gson().fromJson(data, TbMessage.class);
        switch (mActivityStatus) {
            case BasePresenter.ACTIVITY_STATUS_DESTROYED:
                NotificationUtils.startNotificationManager("新的消息", R.mipmap.icon_app, message.getMessageContent());
                break;
            case BasePresenter.ACTIVITY_STATUS_FRONT:
                mView.onReceiveMessage(message);
                refreshFriendList();
                break;
            case BasePresenter.ACTIVITY_STATUS_HIDE:
                NotificationUtils.startNotificationManager("新的消息", R.mipmap.icon_app, message.getMessageContent());
                mView.onReceiveMessage(message);
                refreshFriendList();
                break;
        }

    }

    public void changeActivityStatus(int activityStatus) {
        mActivityStatus = activityStatus;
        InfoRecord.setAtyChatStatus(activityStatus);
    }

    public void getHasNewFriend() {
        String userId = InfoRecord.getUserId();
        if (StringUtils.isEmpty(userId)) {
            toast("用户信息有误");
            return;
        }
        Map<String, String> params = new HashMap<>();
        params.put("id", userId);

        NetWorkBeiyong.request().getApi()
                .hasNewFriend(HttpConfig.HAS_NEW_FRIEND, params)
                .compose(RxUtils.applySchedulersLife())
                .subscribe(new DefaultObserver<HttpResult<HasNewFriendResponseModel>>() {
                    @Override
                    public void onSuccess(HttpResult<HasNewFriendResponseModel> httpResult) {
                        if (httpResult.getCode() == HttpConfig.OK) {
                            HasNewFriendResponseModel model = httpResult.getData();
                            boolean hasNewFriend = model.isHasNewFriend();
                            InfoRecord.setHasNewFriend(hasNewFriend);
                            if (hasNewFriend) {
                                mView.onNewFriendApplyToastAndUpdateMenuUI("");
                            }
                        } else {
                            if (!StringUtils.isEmpty(httpResult.getMessage())) {
                                toast(httpResult.getMessage());
                            }
                        }
                    }
                });
    }

    public void showFriendApplyList(Activity activity) {
        String userId = InfoRecord.getUserId();
        if (StringUtils.isEmpty(userId)) {
            toast("用户信息有误");
            return;
        }
        Map<String, String> params = new HashMap<>();
        params.put("id", userId);

        NetWorkBeiyong.request().getApi()
                .getFriendApplyList(HttpConfig.GET_FRIEND_APPLY_LIST, params)
                .compose(RxUtils.applySchedulersLife())
                .subscribe(new DefaultObserver<HttpResult<NewFriendListResponseModel>>() {
                    @Override
                    public void onSuccess(HttpResult<NewFriendListResponseModel> httpResult) {
                        if (httpResult.getCode() == HttpConfig.OK) {
                            List<FriendApply> invites = httpResult.getData().getInvites();
                            if (invites == null || invites.size() == 0) {
                                ToastUtils.showShort("没有好友申请记录");
                                return;
                            } else {
                                FriendApplyListPop pop = FriendApplyListPop.create(activity, invites);
                                pop.setOnFriendApplyResult(new OnFriendApplyResult() {
                                    @Override
                                    public void onApplyReject(int inviteId, OnCheckFriendApplyCallback onCheckFriendApplyCallback) {
                                        changeFriendApplyStats(null, inviteId, 2, onCheckFriendApplyCallback);

                                    }

                                    @Override
                                    public void onApplyThrough(FriendApply friendApply, OnCheckFriendApplyCallback onCheckFriendApplyCallback) {
                                        changeFriendApplyStats(friendApply, friendApply.getInviteId(), 1, onCheckFriendApplyCallback);
                                    }
                                });
                                pop.showAtLocation(((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0), Gravity.CENTER, 0, 0);
                            }
                        }
                    }
                });
    }

    private void changeFriendApplyStats(FriendApply friendApply, int inviteId, int status, OnCheckFriendApplyCallback onCheckFriendApplyCallback) {
        Map<String, String> params = new HashMap<>();
        params.put("inviteId", String.valueOf(inviteId));
        params.put("inviteStatus", String.valueOf(status));

        NetWorkBeiyong.request().getApi()
                .updateInviteStatus(HttpConfig.UPDATE_INVITE_STATUS, params)
                .compose(RxUtils.applySchedulersLife())
                .subscribe(new DefaultObserver<HttpResult>() {
                    @Override
                    public void onSuccess(HttpResult httpResult) {
                        if (httpResult.getCode() == HttpConfig.OK) {
                            ToastUtils.showShort("操作成功");
                            onCheckFriendApplyCallback.operateResult(true);

                            if (status == 1) {
                                becomeFriends(friendApply);
                            }
                        } else {
                            ToastUtils.showShort(httpResult.getMessage());
                        }
                    }
                });
    }

    @SuppressLint("SimpleDateFormat")
    private void becomeFriends(FriendApply friendApply) {
        // 添加好友成功
        //1. 发送好友接收消息
        //2. 刷新好友列表getFriendList

        SocketPacket packet = SocketPacket.createPacket(DataType.DATA_TYPE_MESSAGE_SEND);
        packet.setCode(DataType.CODE_SOCKET_STATUS_NORMAL);
        TbMessage message = new TbMessage();
        message.setMessageSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        message.setMessageContent("我们已经是好友啦，快来聊天吧！");
        message.setMessageFromUserId(Integer.valueOf(InfoRecord.getUserId()));
        message.setMessageToUserId(friendApply.getInviteFromId());
        message.setMessageType(DataType.MESSAGE_TYPE_TEXT);
        message.setMessageStatus(DataType.MESSAGE_TYPE_STATUS_SENDING);
        packet.setData(new Gson().toJson(message));
        mIMBinder.sendMessage(packet);

        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                refreshFriendList();
            }
        }, 500);
    }

    public void refreshFriendList() {
        Map<String, String> params = new HashMap<>();
        params.put("userId", InfoRecord.getUserId());
        NetWorkBeiyong.request().getApi()
                .getFriendList(HttpConfig.GET_FRIEND_LIST, params)
                .compose(RxUtils.applySchedulersLife())
                .subscribe(new DefaultObserver<HttpResult<GetFriendListResponseModel>>() {
                    @Override
                    public void onSuccess(HttpResult<GetFriendListResponseModel> httpResult) {
                        if (httpResult.getCode() == HttpConfig.OK) {
                            List<FriendModel> friendList = httpResult.getData().getFriendList();
                            if (friendList != null && friendList.size() != 0) {
                                mView.refreshFriendList(friendList);
                            }
                        } else {
                            ToastUtils.showShort(httpResult.getMessage());
                        }
                    }
                });
    }

    private boolean mIsFirstPullMessage = true;

    private int mCurrentFriendId;

    public void setCurrentChatFriend(FriendModel friendModel) {
        InfoRecord.setCurrentChatFriendJson(new Gson().toJson(friendModel));
        mView.setCurrentChatFriendInfo(friendModel);
        // 拉取该朋友的聊天信息
        if (mIsFirstPullMessage || friendModel.getFriendId() != mCurrentFriendId) {
            getMessage(friendModel.getFriendId(), 0, 10, friendModel);
            mIsFirstPullMessage = false;
            mCurrentFriendId = friendModel.getFriendId();
        }
    }

    public void getMessage(int friendId, int fromIndex, int count, FriendModel friendModel) {
        Map<String, String> params = new HashMap<>();
        params.put("userId", InfoRecord.getUserId());
        params.put("friendId", String.valueOf(friendId));
        params.put("fromIndex", String.valueOf(fromIndex));
        params.put("count", String.valueOf(count));
        NetWorkBeiyong.request().getApi()
                .getMessage(HttpConfig.GET_MESSAGE, params)
                .compose(RxUtils.applySchedulersLife())
                .subscribe(new DefaultObserver<HttpResult<GetMessageResponseModel>>() {
                    @Override
                    public void onSuccess(HttpResult<GetMessageResponseModel> httpResult) {
                        if (httpResult.getCode() == HttpConfig.OK) {
                            List<TbMessage> messageList = httpResult.getData().getMessageList();
                            if (messageList != null && messageList.size() != 0) {
                                Collections.reverse(messageList);
                                mView.loadMessage(messageList, friendModel);
                            }
                        } else {
                            ToastUtils.showShort(httpResult.getMessage());
                        }
                    }
                });
    }

    public void getHistoryMessage(int friendId, int fromIndex, int count, FriendModel friendModel) {
        Map<String, String> params = new HashMap<>();
        params.put("userId", InfoRecord.getUserId());
        params.put("friendId", String.valueOf(friendId));
        params.put("fromIndex", String.valueOf(fromIndex));
        params.put("count", String.valueOf(count));
        NetWorkBeiyong.request().getApi()
                .getMessage(HttpConfig.GET_MESSAGE, params)
                .compose(RxUtils.applySchedulersLife())
                .subscribe(new DefaultObserver<HttpResult<GetMessageResponseModel>>() {
                    @Override
                    public void onSuccess(HttpResult<GetMessageResponseModel> httpResult) {
                        if (httpResult.getCode() == HttpConfig.OK) {
                            List<TbMessage> messageList = httpResult.getData().getMessageList();
                            if (messageList != null && messageList.size() != 0) {
                                Collections.reverse(messageList);
                                mView.loadHistoryMessage(messageList, friendModel);
                            } else {
                                mView.stopRefresh();
                            }
                        } else {
                            ToastUtils.showShort(httpResult.getMessage());
                        }
                    }
                });
    }

    public void sendMessage(String message, Integer friendId) {
        SocketPacket packet = SocketPacket.createPacket(DataType.DATA_TYPE_MESSAGE_SEND);
        packet.setCode(DataType.CODE_SOCKET_STATUS_NORMAL);
        TbMessage tbMessage = new TbMessage();
        tbMessage.setMessageSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        tbMessage.setMessageContent(message);
        tbMessage.setMessageFromUserId(Integer.valueOf(InfoRecord.getUserId()));
        tbMessage.setMessageToUserId(friendId);
        tbMessage.setMessageType(DataType.MESSAGE_TYPE_TEXT);
        tbMessage.setMessageStatus(DataType.MESSAGE_TYPE_STATUS_SENDING);
        packet.setData(new Gson().toJson(tbMessage));
        mIMBinder.sendMessage(packet);
    }

    /**
     * 创建类继承ServiceConnection，用于解绑服务方法调用
     */
    public class IMServiceConnection implements ServiceConnection {
        //当客户端正常连接这个服务时，成功绑定到服务时调用该方法。注意IBinder参数对象
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            LogUtils.e("服务绑定成功");
            mIMBinder = (IMService.IMBinder) iBinder;
            startHeartbeat();
        }

        //当客户端与服务失去连接时调用该方法
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            LogUtils.e("服务已解绑");
        }
    }

    public void bindIMService(Context context, int type) {
        if (mIMServiceConnection == null) {
            LogUtils.e("准备绑定服务");
            mIMServiceConnection = new IMServiceConnection();
            Intent intent = new Intent(context, IMService.class);
            //绑定服务,BIND_AUTO_CREATE表示绑定时自动创建Service
            context.bindService(intent, mIMServiceConnection, type);
        }
    }

    private void startHeartbeat() {
        mIMBinder.setSocketResponseListener(this);
        mIMBinder.connectSocketAndPostHeartbeat();
    }

    public void uploadAvatar(String imagePath, String userId) {
        File avatar = new File(imagePath);
        RequestBody photoRequestBody = RequestBody.create(MediaType.parse("image/jpg"), avatar);
        //photos是字段名
        MultipartBody.Part photo = MultipartBody.Part.createFormData("photo", "pic.jpg",
                photoRequestBody);

        NetWorkBeiyong.request().getApi()
                .uploadAvatar(HttpConfig.UPLOAD_AVATAR, photo, RequestBody.create(null, userId))
                .compose(RxUtils.applySchedulersLife())
                .subscribe(new DefaultObserver<HttpResult<UploadAvatarResponseModel>>() {
                    @Override
                    public void onSuccess(HttpResult<UploadAvatarResponseModel> response) {
                        LogUtils.e("response == " + response);
                        if (response.getCode() == HttpConfig.FAIL) {
                            ToastUtils.showShort(response.getMessage());
                            return;
                        }
                        if (!StringUtils.isEmpty(response.getData().getAvatarUrl())) {
                            InfoRecord.setAvatarUrl(response.getData().getAvatarUrl());
                            mView.updateAvatar(response.getData().getAvatarUrl());
                        }
                    }
                });

    }

    public void getUserInfo(String userId) {
        if (!StringUtils.isEmpty(userId)) {
            Map<String, String> params = new HashMap<>();
            params.put("id", userId);

            NetWorkBeiyong.request().getApi()
                    .getUserInfo(HttpConfig.GET_USER_INFO, params)
                    .compose(RxUtils.applySchedulersLife())
                    .subscribe(new DefaultObserver<HttpResult<LoginResponseModel>>() {
                        @Override
                        public void onSuccess(HttpResult<LoginResponseModel> httpResult) {
                            if (httpResult.getCode() == HttpConfig.OK) {
                                LoginResponseModel loginResponseModel = httpResult.getData();
                                LogUtils.e("loginResponseModel == " + loginResponseModel);

                                if (!StringUtils.isEmpty(loginResponseModel.getExt1())) {
                                    if (!loginResponseModel.getExt1().equals(InfoRecord.getNickname())) {
                                        mView.updateNickname(loginResponseModel.getExt1());
                                        InfoRecord.setNickname(loginResponseModel.getExt1());
                                    }
                                }
                                if (!StringUtils.isEmpty(loginResponseModel.getExt2())) {
                                    if (!loginResponseModel.getExt2().equals(InfoRecord.getAvatarUrl())) {
                                        mView.updateAvatar(loginResponseModel.getExt2());
                                        InfoRecord.setAvatarUrl(loginResponseModel.getExt2());
                                    }
                                }
                            } else {
                                if (!StringUtils.isEmpty(httpResult.getMessage())) {
                                    toast(httpResult.getMessage());
                                }
                            }
                        }
                    });
        }
    }

    public void uploadNickname(Activity activity) {
        final EditText editText = new EditText(activity);
        editText.post(() -> {
            ViewGroup.MarginLayoutParams marginLayoutParams = (ViewGroup.MarginLayoutParams) editText.getLayoutParams();
            marginLayoutParams.setMargins(SizeUtils.dp2px(10), 0, SizeUtils.dp2px(10), 0);
            editText.setLayoutParams(marginLayoutParams);
        });
        AlertDialog.Builder inputDialog =
                new AlertDialog.Builder(activity);
        inputDialog.setTitle("请输入昵称：").setView(editText);
        inputDialog.setPositiveButton("确定", (dialog, which) -> {
            String nickname = editText.getText().toString();
            if (StringUtils.isEmpty(nickname)) {
                ToastUtils.showShort("昵称不能为空");
                return;
            } else if (nickname.length() > 8) {
                ToastUtils.showShort("请输入8个字符以内的昵称");
                return;
            } else {
                Map<String, String> params = new HashMap<>();
                params.put("id", InfoRecord.getUserId());
                params.put("ext1", nickname);
                NetWorkBeiyong.request().getApi()
                        .uploadNickname(HttpConfig.UPLOAD_NICKNAME, params)
                        .compose(RxUtils.applySchedulersLife())
                        .subscribe(new DefaultObserver<HttpResult<UploadNicknameResponseModel>>() {
                            @Override
                            public void onSuccess(HttpResult<UploadNicknameResponseModel> httpResult) {
                                if (httpResult.getCode() == HttpConfig.OK) {
                                    String nickname = httpResult.getData().getNickname();
                                    if (!StringUtils.isEmpty(nickname)) {
                                        InfoRecord.setNickname(nickname);
                                        mView.updateNickname(nickname);
                                    }
                                } else {
                                    if (httpResult.getMessage() != null) {
                                        ToastUtils.showShort(httpResult.getMessage());
                                    }
                                }
                            }
                        });
            }
        }).show();
    }

    public void addFriend(Activity activity) {
        final EditText editText = new EditText(activity);
        editText.post(() -> {
            ViewGroup.MarginLayoutParams marginLayoutParams = (ViewGroup.MarginLayoutParams) editText.getLayoutParams();
            marginLayoutParams.setMargins(SizeUtils.dp2px(10), 0, SizeUtils.dp2px(10), 0);
            editText.setLayoutParams(marginLayoutParams);
        });
        AlertDialog.Builder inputDialog =
                new AlertDialog.Builder(activity);
        inputDialog.setTitle("请输入对方用户名(邮箱)：").setView(editText);
        inputDialog.setPositiveButton("确定", (dialog, which) -> {
            String username = editText.getText().toString();
            if (StringUtils.isEmpty(username)) {
                ToastUtils.showShort("用户名(邮箱)不能为空");
                return;
            } else if (username.length() > 20) {
                ToastUtils.showShort("请输入20个字符以内");
                return;
            } else {
                // 调用socket服务添加用户
                SocketPacket packet = SocketPacket.createPacket(DataType.DATA_TYPE_ADD_FRIEND);
                packet.setData(username);
                mIMBinder.addFriend(packet);
            }
        }).show();
    }
}
